/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package me.zhengjie.modules.mnt.rest

import me.zhengjie.modules.mnt.domain.DeployHistory
import cn.hutool.core.io.FileUtil
import cn.hutool.db.PageResult
import io.swagger.v3.oas.annotations.media.Schema
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import me.zhengjie.logging.annotation.Log
import me.zhengjie.modules.mnt.domain.Deploy
import me.zhengjie.modules.mnt.service.DeployService
import me.zhengjie.modules.mnt.service.dto.DeployDto
import me.zhengjie.modules.mnt.service.dto.DeployQueryCriteria
import org.springframework.data.domain.Pageable
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile
import java.io.File
import java.io.IOException
import java.util.*

/**
 * @author zhanghouying
 * @date 2019-08-24
 */
@RestController
@Schema(description = "运维：部署管理")
@RequestMapping("/api/deploy")
class DeployController (
    private val fileSavePath: String = FileUtil.getTmpDirPath() + "/",
    private val deployService: DeployService? = null
){
    @Schema(description ="导出部署数据")
    @GetMapping(value = ["/download"])
    @PreAuthorize("@el.check('database:list')")
    @Throws(
        IOException::class
    )
    fun exportDeployData(response: HttpServletResponse?, criteria: DeployQueryCriteria?) {
        deployService!!.download(deployService!!.queryAll(criteria), response)
    }

    @Schema(description = "查询部署")
    @GetMapping
    @PreAuthorize("@el.check('deploy:list')")
    fun queryDeployData(criteria: DeployQueryCriteria?, pageable: Pageable?): ResponseEntity<PageResult<DeployDto>> {
        return ResponseEntity<PageResult<DeployDto>>(deployService!!.queryAll(criteria, pageable) as PageResult<DeployDto>, HttpStatus.OK)
    }

    @Log("新增部署")
    @Schema(description = "新增部署")
    @PostMapping
    @PreAuthorize("@el.check('deploy:add')")
    fun createDeploy(@Validated @RequestBody resources: Deploy?): ResponseEntity<Any> {
        deployService!!.create(resources)
        return ResponseEntity<Any>(HttpStatus.CREATED)
    }

    @Log("修改部署")
    @Schema(description = "修改部署")
    @PutMapping
    @PreAuthorize("@el.check('deploy:edit')")
    fun updateDeploy(@Validated @RequestBody resources: Deploy?): ResponseEntity<Any> {
        deployService!!.update(resources!!)
        return ResponseEntity<Any>(HttpStatus.NO_CONTENT)
    }

    @Log("删除部署")
    @Schema(description = "删除部署")
    @DeleteMapping
    @PreAuthorize("@el.check('deploy:del')")
    fun deleteDeploy(@RequestBody ids: Set<Long?>?): ResponseEntity<Any> {
        deployService!!.delete(ids!!)
        return ResponseEntity<Any>(HttpStatus.OK)
    }

    @Log("上传文件部署")
    @Schema(description = "上传文件部署")
    @PostMapping(value = ["/upload"])
    @PreAuthorize("@el.check('deploy:edit')")
    @Throws(
        Exception::class
    )
    fun uploadDeploy(@RequestBody file: MultipartFile?, request: HttpServletRequest): ResponseEntity<Any> {
        val id: Long = java.lang.Long.valueOf(request.getParameter("id"))
        var fileName = ""
        if (file != null) {
            fileName = file.originalFilename!!
            val deployFile = File(fileSavePath + fileName)
            FileUtil.del(deployFile)
            file.transferTo(deployFile)
            //文件下一步要根据文件名字来
            deployService!!.deploy(fileSavePath + fileName, id)
        } else {
            println("没有找到相对应的文件")
        }
        println("文件上传的原名称为:" + Objects.requireNonNull<MultipartFile?>(file).getOriginalFilename())
        val map: MutableMap<String, Any> = HashMap(2)
        map["errno"] = 0
        map["id"] = fileName
        return ResponseEntity<Any>(map, HttpStatus.OK)
    }

    @Log("系统还原")
    @Schema(description = "系统还原")
    @PostMapping(value = ["/serverReduction"])
    @PreAuthorize("@el.check('deploy:edit')")
    fun serverReduction(@Validated @RequestBody resources: DeployHistory?): ResponseEntity<Any> {
        val result: String = deployService!!.serverReduction(resources!!)
        return ResponseEntity<Any>(result, HttpStatus.OK)
    }

    @Log("服务运行状态")
    @Schema(description = "服务运行状态")
    @PostMapping(value = ["/serverStatus"])
    @PreAuthorize("@el.check('deploy:edit')")
    fun serverStatus(@Validated @RequestBody resources: Deploy?): ResponseEntity<Any> {
        val result: String = deployService!!.serverStatus(resources!!)
        return ResponseEntity<Any>(result, HttpStatus.OK)
    }

    @Log("启动服务")
    @Schema(description  ="启动服务")
    @PostMapping(value = ["/startServer"])
    @PreAuthorize("@el.check('deploy:edit')")
    fun startServer(@Validated @RequestBody resources: Deploy?): ResponseEntity<Any> {
        val result: String = deployService!!.startServer(resources!!)
        return ResponseEntity<Any>(result, HttpStatus.OK)
    }

    @Log("停止服务")
    @Schema(description  ="停止服务")
    @PostMapping(value = ["/stopServer"])
    @PreAuthorize("@el.check('deploy:edit')")
    fun stopServer(@Validated @RequestBody resources: Deploy?): ResponseEntity<Any> {
        val result: String = deployService!!.stopServer(resources!!)
        return ResponseEntity<Any>(result, HttpStatus.OK)
    }
}